// 引入配置文件
import config from '@/config/index.js';
// sushi-travel/utils/image-cache.js
const CACHE_ROOT_DIR_APP_PLUS = '_doc/image_cache/'; // App端plus.io使用的相对路径，_doc是应用私有文档目录
// #ifdef MP-WEIXIN
const CACHE_ROOT_DIR_MP = `${wx.env.USER_DATA_PATH}/image_cache/`; // 小程序端缓存根目录
// #endif
const CACHE_MAP_KEY = 'sushi_image_cache_map_v3_plusio'; // 缓存映射表的key，版本号用于必要时清空旧映射
const OSS_BASE_URL = config.cdnURL; // 你的CDN域名

// 小程序平台的文件系统管理器
// #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-LARK || MP-KUAISHOU || MP-JD || MP-CLOUD
const fs = uni.getFileSystemManager();
// #endif

// 函数：获取当前平台的缓存根目录绝对路径
function getCacheRootDirAbsolute() {
    // #ifdef APP-PLUS
    return plus.io.convertLocalFileSystemURL(CACHE_ROOT_DIR_APP_PLUS); // 获取_doc/image_cache/的平台绝对路径
    // #endif
    // #ifdef MP-WEIXIN
    return CACHE_ROOT_DIR_MP;
    // #endif
    // #ifdef MP-ALIPAY 
    // 示例: return `${my.env.USER_DATA_PATH}/image_cache/`;
    // #endif
    // ... 其他小程序平台
    // #ifdef H5 
    return ''; // H5无实际本地文件根目录用于此缓存策略
    // #endif
    return ''; // 默认或不支持的平台
}


function getCacheMap() {
    try {
        const map = uni.getStorageSync(CACHE_MAP_KEY);
        return map && typeof map === 'object' ? map : {};
    } catch (e) {
        return {};
    }
}

function setCacheMap(map) {
    try {
        uni.setStorageSync(CACHE_MAP_KEY, map);
    } catch (e) {
        // console.error("保存缓存映射失败:", e);
    }
}

// 函数：确保目录存在 (App端使用plus.io)
function ensureDirectoryExists(path) {
    // #ifdef APP-PLUS
    plus.io.resolveLocalFileSystemURL(path,
        function(entry) {
            // 目录已存在
            if (!entry.isDirectory) {
                // console.warn(`路径 ${path} 已存在但不是目录`);
            }
        },
        function(e) {
            // 目录不存在，尝试创建
            const parentPath = path.substring(0, path.lastIndexOf('/'));
            const rootDirRelative = CACHE_ROOT_DIR_APP_PLUS.slice(0, -1); // 如 _doc/image_cache
            const docDirRelative = '_doc';

            if (parentPath && parentPath !== rootDirRelative && parentPath !== docDirRelative && parentPath.startsWith(docDirRelative)) {
                ensureDirectoryExists(parentPath); // 递归创建父目录
            }
            
            // 创建当前目录，plus.io.requestFileSystem 用于获取根目录的 DirectoryEntry
            plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs_root) {
                // path 是一个类似 "_doc/image_cache/avatar/..." 的相对路径
                // 我们需要从 _doc 之后的部分开始创建
                let relativePathToCreate = path;
                if (path.startsWith('_doc/')) {
                    relativePathToCreate = path.substring('_doc/'.length);
                }

                fs_root.root.getDirectory(relativePathToCreate, { create: true, exclusive: false },
                    function(dirEntry) {
                        // console.log(`目录 ${path} 创建成功或已存在`);
                    },
                    function(error) {
                        // console.warn(`创建目录 ${path} 失败: ${error.message} (code: ${error.code})`);
                    }
                );
            }, function(e) {
                // console.error("请求文件系统失败: " + e.message);
            });
        }
    );
    // #endif

    // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-LARK || MP-KUAISHOU || MP-JD || MP-CLOUD
    if (!fs) return;
    try {
        fs.accessSync(path);
    } catch (e) {
        const parentPath = path.substring(0, path.lastIndexOf('/'));
        const rootDir = getCacheRootDirAbsolute(); 
        
        let isBaseFileSystemDir = false;
        // #ifdef MP-WEIXIN
        if (typeof wx !== 'undefined' && wx.env) {
             isBaseFileSystemDir = (parentPath === wx.env.USER_DATA_PATH);
        }
        // #endif

        if (parentPath && parentPath !== rootDir.slice(0, -1) && !isBaseFileSystemDir) {
            ensureDirectoryExists(parentPath);
        }
        try {
            if (typeof fs.mkdirSync === 'function') {
                fs.mkdirSync(path, { recursive: true });
            }
        } catch (mkdirError) {
            // console.warn(`创建目录 ${path} 失败(MP):`, mkdirError);
        }
    }
    // #endif
}

// 函数：根据服务器URL生成对应的本地存储相对路径 (用于plus.io) 或绝对路径 (用于小程序fs)
function getLocalPathFromServerUrl(networkUrl) {
    if (!networkUrl || !networkUrl.startsWith(OSS_BASE_URL)) {
        return null;
    }

    let pathSegment = networkUrl.replace(OSS_BASE_URL, '');
    if (pathSegment.startsWith('/')) {
        pathSegment = pathSegment.substring(1);
    }
    if (!pathSegment) return null;

    // #ifdef APP-PLUS
    return CACHE_ROOT_DIR_APP_PLUS + pathSegment; // 返回相对路径如 _doc/image_cache/...
    // #endif
    // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-LARK || MP-KUAISHOU || MP-JD || MP-CLOUD
    const rootDir = getCacheRootDirAbsolute();
    return rootDir ? rootDir + pathSegment : null; // 返回绝对路径
    // #endif
    // #ifdef H5
    return null; // H5不使用此函数生成本地路径
    // #endif
    return null;
}


async function getImage(networkUrl) {
    if (!networkUrl || typeof networkUrl !== 'string' || !networkUrl.startsWith('http')) {
        return networkUrl;
    }
    if (!networkUrl.startsWith(OSS_BASE_URL)) {
        return networkUrl;
    }

    // #ifdef H5
    return networkUrl;
    // #endif

    const cacheMap = getCacheMap();
    const localPathFromMap = cacheMap[networkUrl]; // 这个路径可能是相对的(App)或绝对的(MP)

    // #ifdef APP-PLUS
    if (localPathFromMap) { // localPathFromMap 是 "_doc/image_cache/..."
        const absolutePath = plus.io.convertLocalFileSystemURL(localPathFromMap);
        try {
            // 使用 plus.io.resolveLocalFileSystemURL 检查文件是否存在更可靠
            await new Promise((resolve, reject) => {
                plus.io.resolveLocalFileSystemURL(absolutePath, resolve, (err) => {
                    reject(err);
                });
            });
            // console.log('App缓存命中:', absolutePath);
            return absolutePath; // 返回平台绝对路径用于显示
        } catch (e) {
            // console.log('App缓存失效，从映射中移除:', localPathFromMap);
            delete cacheMap[networkUrl];
            setCacheMap(cacheMap);
        }
    }
    // #endif

    // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-LARK || MP-KUAISHOU || MP-JD || MP-CLOUD
    if (localPathFromMap) { // localPathFromMap 是小程序的绝对路径
        if (!fs) return networkUrl;
        try {
            fs.accessSync(localPathFromMap);
            // console.log('小程序缓存命中:', localPathFromMap);
            return localPathFromMap;
        } catch (e) {
            // console.log('小程序缓存失效，从映射中移除:', localPathFromMap);
            delete cacheMap[networkUrl];
            setCacheMap(cacheMap);
        }
    }
    // #endif


    const targetLocalPathRelativeOrAbsolute = getLocalPathFromServerUrl(networkUrl); // App返回相对，MP返回绝对
    if (!targetLocalPathRelativeOrAbsolute) {
        return networkUrl;
    }

    // #ifdef APP-PLUS
    const dirPathRelative = targetLocalPathRelativeOrAbsolute.substring(0, targetLocalPathRelativeOrAbsolute.lastIndexOf('/'));
    ensureDirectoryExists(dirPathRelative); // App端使用相对路径创建目录
    // #endif
    // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-LARK || MP-KUAISHOU || MP-JD || MP-CLOUD
    if (fs) {
        const dirPathAbsolute = targetLocalPathRelativeOrAbsolute.substring(0, targetLocalPathRelativeOrAbsolute.lastIndexOf('/'));
        ensureDirectoryExists(dirPathAbsolute); // 小程序端使用绝对路径创建目录
    } else {
        return networkUrl; // 如果小程序文件系统不可用
    }
    // #endif

    try {
        const downloadResult = await uni.downloadFile({ url: networkUrl });
        if (downloadResult.statusCode === 200 && downloadResult.tempFilePath) {
            // #ifdef APP-PLUS
            // App端，targetLocalPathRelativeOrAbsolute 是 "_doc/image_cache/..."
            // plus.io.PRIVATE_DOC 指向 _doc 目录
            return new Promise((resolve, reject) => {
                 plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs_root) {
                    let relativeToDoc = targetLocalPathRelativeOrAbsolute;
                    if(relativeToDoc.startsWith('_doc/')) {
                        relativeToDoc = relativeToDoc.substring('_doc/'.length);
                    }
                    // 先尝试删除旧文件
                    fs_root.root.getFile(relativeToDoc, {create:false}, function(fileEntry){
                        fileEntry.remove(function(){
                             moveFile(); // 删除成功后移动
                        }, function(){
                             moveFile(); // 删除失败也尝试移动（可能文件本不存在）
                        });
                    }, function(){
                        moveFile(); // 文件不存在，直接移动
                    });

                    function moveFile() {
                        plus.io.resolveLocalFileSystemURL(downloadResult.tempFilePath, function(tempEntry) {
                            fs_root.root.getDirectory(relativeToDoc.substring(0, relativeToDoc.lastIndexOf('/')), { create: true }, function (dirEntry) {
                                tempEntry.moveTo(dirEntry, relativeToDoc.substring(relativeToDoc.lastIndexOf('/') + 1), function(entry) {
                                    const finalPathForDisplay = entry.toLocalURL(); // 或 entry.fullPath, toURL()
                                    cacheMap[networkUrl] = targetLocalPathRelativeOrAbsolute; // 存储相对路径到map
                                    setCacheMap(cacheMap);
                                    // console.log('App文件保存成功:', finalPathForDisplay);
                                    resolve(finalPathForDisplay);
                                }, function(err) {
                                    // console.error('App移动文件失败:', err.message, '目标:', relativeToDoc);
                                    reject(err);
                                });
                            }, function(err){
                                // console.error('App获取目标目录失败:', err.message);
                                reject(err);
                            });
                        }, function(err){
                            // console.error('App解析临时文件路径失败:', err.message);
                            reject(err);
                        });
                    }

                }, function(e) {
                    // console.error("App请求文件系统失败: " + e.message);
                    reject(e);
                });
            }).catch(() => networkUrl); // 内部Promise reject时，返回网络URL
            // #endif

            // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-LARK || MP-KUAISHOU || MP-JD || MP-CLOUD
            if (!fs) return networkUrl;
            try {
                fs.accessSync(targetLocalPathRelativeOrAbsolute);
                fs.unlinkSync(targetLocalPathRelativeOrAbsolute);
            } catch (e) {
                // 文件不存在
            }
            const saveResult = await new Promise((resolve, reject) => {
                fs.saveFile({
                    tempFilePath: downloadResult.tempFilePath,
                    filePath: targetLocalPathRelativeOrAbsolute,
                    success: (res) => {
                        resolve(targetLocalPathRelativeOrAbsolute);
                    },
                    fail: (err) => reject(err)
                });
            });
            cacheMap[networkUrl] = saveResult;
            setCacheMap(cacheMap);
            return saveResult;
            // #endif
            
            // 对于不支持的平台或fs未初始化的情况
            // #ifndef APP-PLUS || MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-LARK || MP-KUAISHOU || MP-JD || MP-CLOUD
            return networkUrl;
            // #endif

        } else {
            return networkUrl;
        }
    } catch (error) {
        return networkUrl;
    }
}

function clearCache(networkUrl) {
    const cacheMap = getCacheMap();
    if (networkUrl) {
        const localPathRelativeOrAbsolute = cacheMap[networkUrl];
        if (localPathRelativeOrAbsolute) {
            // #ifdef APP-PLUS
            const absolutePath = plus.io.convertLocalFileSystemURL(localPathRelativeOrAbsolute);
            plus.io.resolveLocalFileSystemURL(absolutePath, function(entry) {
                entry.remove(function() { /* console.log('App缓存文件删除成功:', absolutePath); */ },
                           function(err) { /* console.warn('App删除缓存文件失败:', err.message); */ });
            }, function(err) { /* 文件可能已被删除或路径无效 */ });
            // #endif
            // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-LARK || MP-KUAISHOU || MP-JD || MP-CLOUD
            if (fs) {
                try { fs.unlinkSync(localPathRelativeOrAbsolute); } catch (e) { /* console.warn('小程序删除缓存文件失败:', e); */ }
            }
            // #endif
            delete cacheMap[networkUrl];
            setCacheMap(cacheMap);
        }
    }
}

function clearAllCache() {
    const cacheMap = getCacheMap();
    Object.entries(cacheMap).forEach(([netUrl, localPathRelOrAbs]) => {
        clearCache(netUrl); // 调用单个清理，它会处理平台差异
    });
    uni.removeStorageSync(CACHE_MAP_KEY); // 清空整个映射表 (clearCache已处理单个条目，这里是最终确认)

    // #ifdef APP-PLUS
    plus.io.resolveLocalFileSystemURL(CACHE_ROOT_DIR_APP_PLUS, function(entry) {
        entry.removeRecursively(function() { /* console.log('App缓存目录已递归删除'); */ },
                                function(err) { /* console.error('App递归删除缓存目录失败:', err.message); */ });
    }, function(err){ /* 目录可能不存在 */});
    // #endif

    // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-LARK || MP-KUAISHOU || MP-JD || MP-CLOUD
    if (fs) {
        const rootDirAbs = getCacheRootDirAbsolute();
        try {
            fs.rmdirSync(rootDirAbs, { recursive: true });
            // console.log('小程序缓存目录已删除:', rootDirAbs);
        } catch (e) {
            // console.error('小程序清理缓存根目录失败:', e);
        }
    }
    // #endif
}


async function preloadImages(urls) {
    if (!Array.isArray(urls)) {
        urls = [urls];
    }
    const validUrls = urls.filter(url => url && typeof url === 'string' && url.startsWith(OSS_BASE_URL));
    if (validUrls.length === 0) return;

    for (const url of validUrls) {
        await getImage(url);
    }
}

export default {
    getImage,
    clearCache,
    clearAllCache,
    preloadImages,
    OSS_BASE_URL
};